const config = require('./config');
const porject = require('./config/project');
const path = require('path');
const chalk = require('chalk');
const gulp = require('gulp');
const gulpif = require('gulp-if');
const htmlmin = require('gulp-htmlmin');
const fileinclude = require('gulp-file-include');
const sass = require('gulp-sass');
const postcss = require('gulp-postcss');
const cleanCSS = require('gulp-clean-css');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const cache = require('gulp-cache');
const imagemin = require('gulp-imagemin');
const pngquant = require('imagemin-pngquant');
const uglify = require('gulp-uglify');
const eslint = require('gulp-eslint');
const stripDebug = require('gulp-strip-debug');
const babel = require('gulp-babel');
const sequence = require('gulp-sequence');
const zip = require('gulp-zip');
const del = require('del');
const watch = require('gulp-watch');
const sourcemaps = require('gulp-sourcemaps');
const argv = require('minimist')(process.argv.slice(2));
const replace = require('gulp-replace');
const spritesmith = require('gulp.spritesmith'); //雪碧图
// webpack
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const webpackConfig = require('./webpack.config.js');
const htmlBeautify = require('gulp-html-beautify');
// server
const browserSync = require('browser-sync').create();
const reload = browserSync.reload;

// NODE_ENV
const env = process.env.NODE_ENV || 'development';
const condition = env === 'production';
let width_design = 0;

function respath (dir) {
  return path.join(__dirname, './', porject.name, dir);
}

function onError (error) {
  const title = error.plugin + ' ' + error.name;
  const msg = error.message;
  const errContent = msg.replace(/\n/g, '\\A ');

  notify.onError({
    title: title,
    message: errContent,
    sound: true,
  })(error);

  this.emit('end');
}

function cbTask (task) {
  return new Promise((resolve, reject) => {
    del(respath('dist')).then((paths) => {
      console.log(
        chalk.green(`
      -----------------------------
        Clean tasks are completed
      -----------------------------`)
      );
      sequence(task, () => {
        console.log(
          chalk.green(`
        -----------------------------
          All tasks are completed
        -----------------------------`)
        );
        resolve('completed');
      });
    });
  });
}
//雪碧图
gulp.task('sprite', function () {
  return gulp
    .src([config.dev.sprite, '!./**/sprite.png']) //需要合并的图片地址
    .pipe(
      spritesmith({
        imgName:
          porject.name + '/src/' + config.staticName + '/images/sprite.png', //保存合并后图片的地址
        cssName:
          porject.name + '/src/' + config.staticName + '/styles/sprite.scss', //保存合并后对于css样式的地址
        padding: 5, //合并时两个图片的间距
        algorithm: 'binary-tree', //注释1
        cssTemplate:
          porject.name + '/src/' + config.staticName + '/styles/handlebarsStr', //注释2
      })
    )
    .pipe(gulp.dest('./'));
  // .pipe(gulp.dest(config.src));
});

gulp.task('html', () => {
  return (
    gulp
      .src(config.dev.html)
      .pipe(plumber(onError))
      .pipe(
        fileinclude({
          context: {
            images: './' + config.staticName + '/images',
          },
          prefix: '@@',
          basepath: respath('/src/include/'),
        })
      )
      .pipe(
        htmlBeautify({
          indent_size: 2,
          // indent_char: ' ',
          // 这里是关键，可以让一个标签独占一行
          unformatted: true,
        })
      )
      // .pipe(gulpif(condition, htmlmin({
      //   removeComments: true,
      //   collapseWhitespace: true,
      //   minifyJS: true,
      //   minifyCSS: true
      // })))
      .pipe(gulp.dest(config.build.html))
  );
});

gulp.task('styles', () => {
  // return gulp.src(config.dev.styles)
  return gulp
    .src(
      porject.name.includes('xsl')
        ? config.dev.styles
        : porject.name + '/src/' + config.staticName + '/styles/style.scss'
    )
    .pipe(plumber(onError))
    .pipe(gulpif(!condition, sourcemaps.init()))
    .pipe(sass())
    .pipe(gulpif(condition, cleanCSS({ debug: true })))
    .pipe(postcss('./.postcssrc.js'))
    .pipe(gulpif(!condition, sourcemaps.write()))
    .pipe(gulp.dest(config.build.styles));
});

gulp.task('images', () => {
  return (
    gulp
      .src(config.dev.images)
      .pipe(plumber(onError))
      // .pipe(cache(gulpif(condition, imagemin({
      //   progressive: true, // 无损压缩JPG图片
      //   svgoPlugins: [{removeViewBox: false}], // 不移除svg的viewbox属性
      //   use: [pngquant()] // 使用pngquant插件进行深度压缩
      // }))))
      // .pipe(cache())
      .pipe(gulp.dest(config.build.images))
  );
});

gulp.task('eslint', () => {
  return gulp
    .src(config.dev.script)
    .pipe(plumber(onError))
    .pipe(gulpif(condition, stripDebug()))
    .pipe(eslint({ configFle: './.eslintrc' }))
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});

const useEslint = config.useEslint ? ['eslint'] : [];
gulp.task('script', useEslint, () => {
  return (
    gulp
      .src(config.dev.script)
      .pipe(plumber(onError))
      .pipe(
        gulpif(
          condition,
          babel({
            presets: ['env'],
          })
        )
      )
      .pipe(gulpif(config.useWebpack, webpackStream(webpackConfig, webpack)))
      // .pipe(gulpif(condition, uglify()))
      .pipe(gulp.dest(config.build.script))
  );
});

gulp.task('static', () => {
  return gulp.src(config.dev.static).pipe(gulp.dest(config.build.static));
});

gulp.task('clean', () => {
  del(porject.name + '/dist').then((paths) => {
    console.log('Deleted files and folders:\n', paths.join('\n'));
  });
});

gulp.task('watch', () => {
  // gulp.watch(config.dev.allhtml, ['html']).on('change', reload)
  // gulp.watch(config.dev.styles, ['styles']).on('change', reload)
  // gulp.watch(config.dev.script, ['script']).on('change', reload)
  // gulp.watch(config.dev.images, ['images']).on('change', reload)
  // gulp.watch(config.dev.static, ["static"]).on("change", reload);
  w(config.dev.allhtml, 'html');
  w(config.dev.sprite, 'sprite');
  w(config.dev.styles, 'styles');
  w(config.dev.script, 'script');
  w(config.dev.images, 'images');
  w(config.dev.static, 'static');
  function w (path, task) {
    let t = null;
    let times =
      path == config.dev.sprite || path == config.dev.images ? 2000 : 1000;
    watch(path, function () {
      if (t) {
        clearTimeout(t);
        t = null;
      }
      t = setTimeout(function () {
        try {
          run(task);
        } catch (e) {
          console.log(e);
        }
        t = null;
      }, times);
    });
  }
  function run (task) {
    gulp.start(task);
    setTimeout(() => { reload(); }, 1500)
  }
});

gulp.task('zip', () => {
  return gulp
    .src(config.zip.path)
    .pipe(plumber(onError))
    .pipe(zip(config.zip.name))
    .pipe(gulp.dest(config.zip.dest));
});

gulp.task('server', () => {
  const task = ['html', 'sprite', 'styles', 'script', 'images', 'static']; //, 'static'
  cbTask(task).then(() => {
    browserSync.init(config.server);
    console.log(chalk.cyan('  Server complete.\n'));
    gulp.start('watch');
  });
});

gulp.task('build', () => {
  const task = ['html', 'sprite', 'styles', 'script', 'images', 'static']; //, 'static'
  cbTask(task).then(() => {
    console.log(chalk.cyan('  Build complete.\n'));

    if (config.productionZip) {
      // gulp.start('zip', () => {
      //   console.log(chalk.cyan('  Zip complete.\n'))
      // })
    }
  });
});
gulp.task('buildBat', () => {
  const task = ['html', 'sprite', 'styles', 'script', 'images', 'static']; //, 'static'
  cbTask(task).then(() => {
    console.log(chalk.cyan('  Build complete.\n'));
    let cp = require('child_process');
    // const argv = require('minimist')(process.argv.slice(2));
    batDo(config.name.split('/'));
  });
});
// 创建项目
gulp.task('creatProject', ['changeProjectName'], function () {
  return gulp
    .src('./tem/**/*') //
    .pipe(gulp.dest('./apps/' + argv.proName + '/src'));
});
// 更改开发项目名
gulp.task('changeProjectName', function () {
  return gulp
    .src('./config/project.js') //
    .pipe(replace(porject.name, './apps/' + argv.proName))
    .pipe(gulp.dest('./config'));
});
//当前项目是
gulp.task('nowporjectname', function () {
  console.log('  ');
  console.log('  ');
  console.log('现在的项目目录是：');
  console.log('############################################# ');
  console.log('　　  ' + porject.name.split('/')[1]);
  console.log('############################################# ');
  console.log('  ');
  console.log('  ');
});
gulp.task('default', () => {
  console.log(
    chalk.green(
      `
  Build Setup
    开发环境： npm run dev
    生产环境： npm run build
    执行压缩： gulp zip
    编译页面： gulp html
    编译脚本： gulp script
    编译样式： gulp styles
    语法检测： gulp eslint
    压缩图片： gulp images
    `
    )
  );
});
function batDo (name) {
  name = name[name.length - 1];
  if (name) {
    console.log('开始处理压缩任务');
    let cp = require('child_process');
    cp.exec(
      `cd G:/task/workSpace/compressWeb &&gulp --name ${name}&& gulp copy --name ${name}`,
      function (err, stdout) {
        console.log(stdout);
        if (err) {
        } else {
          console.log('ok');
        }
      }
    );
  } else {
    console.log('没有代入name');
    process.exit(0);
  }
}
